package com.weng.platform.guest.api;

import com.weng.framework.core.model.ResponseData;
import com.weng.framework.web.base.BaseController;
import com.weng.platform.article.model.vo.ArticleInfoDetailVo;
import com.weng.platform.article.service.IArticleInfoService;
import com.weng.platform.guest.entity.GuestVisitLog;
import com.weng.platform.guest.service.IGuestVisitLogService;
import com.weng.platform.resource.entity.Resource;
import com.weng.platform.resource.service.IResourceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 文章基本信息表 前端控制器
 *
 * @author wenghui
 * @date 2019-11-30 10:48:30
 *
 */  
@Slf4j
@RestController
@RequestMapping("/guest")
@Api(value = "访客api", tags = {"访客api"})
public class GuestApi extends BaseController {
    @Autowired
    private IArticleInfoService articleInfoService;
		@Autowired
		private IResourceService resourceService;

		@Autowired
		private IGuestVisitLogService guestVisitLogService;

		// 访问统计临时缓存,主键为用户名+资源Id
		private static ConcurrentHashMap<String,Long> VISIT_COUNT_CACHE_OF_URER_AND_RESOURCE = new ConcurrentHashMap();
		// 访问统计临时缓存
		private static ConcurrentHashMap<String,Integer> VISIT_COUNT_CACHE_OF_RESOURCE = new ConcurrentHashMap();

    /**
     * 功能描述:单个获取文章基本信息表
     */
    @ApiOperation(value = "获取文章详细信息", notes = "")
    @GetMapping(value = "/article-info/get")
    public ResponseData getArticle(String id){
		ArticleInfoDetailVo articleInfo = articleInfoService.getArticleInfoDetail(id);
        return success(articleInfo);
    }


	@ApiOperation(value = "获取资源信息", notes = "")
	@GetMapping(value = "/mapper/resource/get")
	public ResponseData get(String id){
		Resource resource = resourceService.getById(id);
		return success(resource);
	}

	@ApiOperation(value = "增加资源访问记录", notes = "")
	@PostMapping(value = "/mapper/resource/visit/logs")
	public ResponseData visitLogs(String resourceId, String visitor, String type, HttpServletRequest request){
		addVisitLogs(resourceId, visitor, type, request);
		return success();
	}

	public String getRemoteIP(HttpServletRequest request) {

    if(request.getHeader("X-Real-IP") != null){
    	return request.getHeader("X-Real-IP");
		}
		if (request.getHeader("x-forwarded-for") == null) {
			return request.getRemoteAddr();
		}
		return request.getHeader("x-forwarded-for");
	}

	private void addVisitLogs(String resourceId, String visitor, String type, HttpServletRequest request){
		long currentTime = System.currentTimeMillis();
		String key = visitor + "#" + resourceId;
		String requestIp = getRemoteIP(request);
		// key 的规则,匿名的且请求IP非内网，则加上IP，避免重复计算
		if("匿名".equalsIgnoreCase(visitor) && requestIp.indexOf("192.") != 0){
			key +=  "#" + requestIp;
		}
		Long lastVisitTime = VISIT_COUNT_CACHE_OF_URER_AND_RESOURCE.get(key);
		if((lastVisitTime != null) && ((currentTime - lastVisitTime) < (10 * 60 * 1000))){
			return;
		}
		VISIT_COUNT_CACHE_OF_URER_AND_RESOURCE.put(key, currentTime);
		GuestVisitLog guestVisitLog = new GuestVisitLog();
		guestVisitLog.setResourceId(resourceId);
		guestVisitLog.setVisitorName(visitor);
		guestVisitLog.setType(type);
		guestVisitLog.setRequestIp(requestIp);
		guestVisitLogService.add(guestVisitLog);
		addResourceVisitCount(resourceId);
	}

	private static void  addResourceVisitCount(String id){
    	if(StringUtils.isNotEmpty(id)){
				Integer visitCount = VISIT_COUNT_CACHE_OF_RESOURCE.get(id);
				visitCount = visitCount == null ? 0 : visitCount;
				visitCount += 1;
				VISIT_COUNT_CACHE_OF_RESOURCE.put(id, visitCount);
			}
	}

	/*
	 * 定时任务
	 */
	@Scheduled(cron = "0/50 * * * * ?")
	private void schedule(){
		if(VISIT_COUNT_CACHE_OF_RESOURCE.size() > 0){
			for(Map.Entry<String,Integer> entry : VISIT_COUNT_CACHE_OF_RESOURCE.entrySet()){
				resourceService.incVisitCount(entry.getKey(), entry.getValue());
			}
			VISIT_COUNT_CACHE_OF_RESOURCE.clear();
		}
	}


}
